CA65 ?= ca65
LD65 ?= ld65
PYTHON ?= python3
NESDIS ?= ../../../_tools/nesdis.py

all: reconstructed.nes verify

prg.o: prg.s symbols.inc locals.inc prg.bin
	$(CA65) -g -o $@ $<

header.o: header.s header.bin
	$(CA65) -g -o $@ $<

chr.o: chr.s chr.bin
	$(CA65) -g -o $@ $<

reconstructed.nes: header.o prg.o chr.o linker.cfg
	$(LD65) -C linker.cfg -m reconstructed.map -Ln reconstructed.lbl -o $@ header.o prg.o chr.o

verify: reconstructed.nes rom.nes
	cmp reconstructed.nes rom.nes
	@echo "Byte-identical ROM verified."

# Regenerate prg.s from prg.bin.  Every flag below is a documented
# classification decision, not a convenience; see the header block of prg.s
# and README.md.
#
# --undocumented       the code uses undocumented NMOS opcodes as ordinary code
# --table 0xF796:5    the event dispatch table, read at $F780 and jumped to
#                      through `jmp ($001F)`; the values are direct addresses
# --extra-seed         the 25 entries of the three push-pointer dispatch tables
#                      ($BFC4, $BFE4, $E5F2).  Those tables store the handler
#                      address MINUS ONE, because the handler is pushed and an
#                      `rts` lands on it, so the seeds are the table values + 1
# --data 0xC0BE:8     the dead IRQ vector area, forced back to data
PASS1_SEEDS = 0xBFF8,0xC00A,0xC015,0xC029,0xC037,0xC04F,0xC057,0xC07B,0xC083,0xC097,0xC0AD,0xC0C1,0xC0D1,0xC0F8,0xC129,0xC134,0xBFE8,0xBFF0,0xE0EF,0xE16D,0xE20D,0xE2DE,0xE42A,0xE52C

pass1:
	$(PYTHON) $(NESDIS) --prg prg.bin --base 0x8000 \
	    --project "World Class Track Meet (U)" --out prg.s --locals locals.inc \
	    --auto-seed --undocumented --table 0xF796:5 --data 0xC0BE:8 \
	    --extra-seed "$(PASS1_SEEDS)" \
	    --mapping-note 'CNROM, mapper 3: the whole 32 KB image is visible at $$8000-$$FFFF' \
	    --provenance 'the PRG is 32 KB and maps whole at $$8000-$$FFFF (CNROM, mapper 3), so the linker puts the PRG segment at $$8000 rather than at a file offset' \
	    --provenance 'dispatch table $$F796, 5 entries, read by `lda $$F796,y` at $$F780 and jumped to through `jmp ($$001F)`' \
	    --provenance 'push-pointer dispatch tables $$BFC4 (16 entries), $$BFE4 (2) and $$E5F2 (7): the handler address is pushed and an `rts` lands on it, so each table stores the entry address MINUS ONE - the seeds above are the table values plus one' \
	    --provenance 'the reason $$C0BE-$$C0C5 is data: the IRQ vector $$C0C0 points into the middle of the `jmp $$C047` at $$C0BE, and the game never executes CLI, so the vector is dead' \
	    --provenance 'the tracer is run with --undocumented: the code uses undocumented opcodes as ordinary code (ANC $$37 at $$BFF8, RRA/RLA/SLO and the NOP forms elsewhere)'

clean:
	rm -f *.o reconstructed.nes reconstructed_prg.bin reconstructed.map reconstructed.lbl

.PHONY: all verify clean pass1
